/**
 * Copyright (C) 2017-2018 pinganfang, Inc. All Rights Reserved.
 */
package com.pingan.haofang.searchcloud.common.utils;

import org.springframework.util.Assert;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author huhailiang937
 * @date 2017年4月7日下午11:40:05
 * @since 1.0.0
 */
public class DateUtils {

    public static final int YEAR_RETURN = 0;

    public static final int MONTH_RETURN = 1;

    public static final int DAY_RETURN = 2;

    public static final int HOUR_RETURN = 3;

    public static final int MINUTE_RETURN = 4;

    public static final int SECOND_RETURN = 5;

    public static final long second_unit = 1000;

    public static String formatDate(final Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getFormatDate(final Date date) {
        return formatDate(date, "yyyyMMdd");

    }

    /**
     * 将形如20180420 转成 当天最后一刻的时间 2018-04-20 23:59:59
     */
    public static Date getTheDayLastTime(String date, String pattern) throws ParseException {
        Assert.notNull(date, "Date");
        Assert.notNull(pattern, "Pattern");
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        Date res = formatter.parse(date);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(res);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public static Date getTheDayLastTime(Date date) throws ParseException {
        Assert.notNull(date, "Date");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }


    /**
     * 获取指定日期几天前的日期
     * @param date
     * @param days 减去几天
     * @return
     */
    public static Date getDateBefore(Date date,Integer days){
        Assert.notNull(date, "Date can not be null");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE,-days);
        return calendar.getTime();
    }


    public static Date parseDate(String date, String pattern) throws ParseException {
        Assert.notNull(date, "Date");
        Assert.notNull(pattern, "Pattern");
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.parse(date);
    }

    public static String formatDate(final Date date, final String pattern) {
        Assert.notNull(date, "Date");
        Assert.notNull(pattern, "Pattern");
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.format(date);
    }

    public static int getBetweenDays(final Date beginDate, final Date endDate) {
        Long dateBetween = getBetween(beginDate, endDate, DAY_RETURN);
        return dateBetween.intValue();
    }

    /**
     * 最大化查询日期
     *
     * eg：<br>
     * 输入2017-01-01，输出2017-01-01 23:59:59<br>
     * 输入2017-01-01 12:12:12，输出2017-01-01 23:59:59<br>
     *
     * @param date
     */
    public static Date upper(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        return c.getTime();
    }

    /**
     * 最小化查询日期
     *
     * @param date
     * @return
     */
    public static Date down(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }


    public static Long getBetween(final Date beginDate, final Date endDate, int returnPattern) {
        Assert.notNull(beginDate, "beginDate can not null");
        Assert.notNull(endDate, "endDate can not null");

        Calendar beginCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        beginCalendar.setTime(beginDate);
        endCalendar.setTime(endDate);
        endCalendar.setTime(endDate);
        switch (returnPattern) {
            case YEAR_RETURN:
                return DateUtils.getByField(beginCalendar, endCalendar, Calendar.YEAR);
            case MONTH_RETURN:
                return DateUtils.getByField(beginCalendar, endCalendar, Calendar.YEAR) * 12
                        + DateUtils.getByField(beginCalendar, endCalendar, Calendar.MONTH);
            case DAY_RETURN:
                return DateUtils.getTime(beginDate, endDate) / (24 * 60 * 60 * 1000);
            case HOUR_RETURN:
                return DateUtils.getTime(beginDate, endDate) / (60 * 60 * 1000);
            case MINUTE_RETURN:
                return DateUtils.getTime(beginDate, endDate) / (60 * 1000);
            case SECOND_RETURN:
                return DateUtils.getTime(beginDate, endDate) / 1000;
            default:
                return 0L;
        }
    }

    private static long getByField(Calendar beginCalendar, Calendar endCalendar, int calendarField) {
        return endCalendar.get(calendarField) - beginCalendar.get(calendarField);
    }

    private static long getTime(Date beginDate, Date endDate) {
        return endDate.getTime() - beginDate.getTime();
    }

    public static long conv2Seconds(long millisecond) {
        return millisecond/second_unit;
    }

}
